﻿using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Client.Common;
using Client.DAL;

using Models;
using Newtonsoft.Json;
using Panuon.UI.Silver;

using Prism.Commands;
using Prism.Mvvm;

using Taxhui.Utils.CryptUtils;

namespace Client.ViewModels
{
    public class LoginViewModel : BindableBase
    {
        #region 绑定属性

        //提示语
        private string _connState;

        public string ConnState
        {
            get { return _connState; }
            set { SetProperty(ref _connState, value, "ConnState"); }
        }

        private string _userName;

        public string UserName
        {
            get { return _userName; }
            set { SetProperty(ref _userName, value); }
        }

        private bool _savePass;

        public bool SavePass
        {
            get { return _savePass; }
            set { SetProperty(ref _savePass, value); }
        }

        private bool _logingIn;

        public bool LogingIn
        {
            get { return _logingIn; }
            set { SetProperty(ref _logingIn, value); }
        }

        private bool _canLogin;

        public bool CanLogin
        {
            get { return _canLogin; }
            set
            {
                SetProperty(ref _canLogin, value, "CanLogin");
                LoginCommand?.RaiseCanExecuteChanged();
            }
        }

        private string _logContent;

        public string LogingContent
        {
            get { return _logContent; }
            set { SetProperty(ref _logContent, value, "LogingContent"); }
        }

        #endregion 绑定属性

        #region 变量

        private readonly Action _closeMethod;
        private int _connCount = 0;
        public Window Win;

        #endregion 变量

        #region 命令

        public DelegateCommand<PasswordBox> LoginCommand { get; private set; }
        public DelegateCommand CloseCommand { get; private set; }
        public DelegateCommand OpenSetCommand { get; private set; }

        #endregion 命令

        #region 构造函数

        public LoginViewModel(Action closeMethod)
        {
            LogingIn = false;
            CanLogin = false;
            SavePass = false;
            LogingContent = "登录中";
            Comm.UserInfo = null;
            _closeMethod = closeMethod;
            LoginCommand = new DelegateCommand<PasswordBox>(Login, (args) => { return CanLogin; });
            CloseCommand = new DelegateCommand(Close);
            OpenSetCommand = new DelegateCommand(OpenSet);
            LoadConfig();
        }

        #endregion 构造函数

        #region 方法

        //连接服务器
        private void ConnectToServer()
        {
            Comm.NetCtrl.InitClient(Comm.CFG.ServerAddr, Comm.CFG.ServerPort, Connected, ConnectFailed);
        }

        private void Connected()
        {
            ConnState = "状态：连接服务器成功";
            Application.Current.Dispatcher.Invoke(() => CanLogin = true);
        }

        private void ConnectFailed()
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                ConnState = "状态：连接服务器失败(失败" + _connCount + "次)";
                _connCount++;
                CanLogin = false;
            });
        }

        //登录
        private StateModel loginState;

        private async void Login(PasswordBox p)
        {
            if (!CanLogin)
                return;
            string pwd = SavePass && string.IsNullOrEmpty(p.Password) ? Comm.CFG.SavedPass : p.Password;
            LogingIn = true;
            CanLogin = false;

            loginState = new StateModel { CurStep = Steps.Send };
            UserModel um = new UserModel { UserName = UserName, Password = MD5Crypt.MD32Crypt(pwd) };
            UserSrv.Login(LoginCallback, um);
            await loginState.CheckState(10);
            if (loginState.CurStep == Steps.Succ)
            {
                CanLogin = true;
                LogingIn = false;
                //服务器返回的用户信息
                Comm.UserInfo = loginState.RM.Data as UserModel;
                //保存密码
                Comm.CFG.IsSavePass = SavePass;
                Comm.CFG.SavedPass = SavePass ? pwd : "";
                Comm.CFG.SavedUser = SavePass ? UserName : "";
                Comm.SaveConfig();
                LogingIn = false;
                _closeMethod();
                return;
            }
            CanLogin = true;
            LogingIn = false;
            MessageBoxX.Show($"登录失败：\r\n错误代码:{loginState.RM.ErrCode}\r\n错误信息:{loginState.RM.ErrInfo}", "系统登录", null, MessageBoxButton.OK, new MessageBoxXConfigurations()
            {
                MessageBoxIcon = MessageBoxIcon.Error,
                MessageBoxStyle = MessageBoxStyle.Modern,
                OKButton = "确定",
                DefaultButton = DefaultButton.YesOK,
                WindowStartupLocation = WindowStartupLocation.CenterScreen
            });
        }

        //登录回调
        private void LoginCallback(RetModel rm)
        {
            if (loginState.CurStep != Steps.Send) return;
            loginState.RM = rm;
            loginState.RM.Data = rm.Success ?rm.Data is null?null: JsonConvert.DeserializeObject<UserModel>(rm.Data?.ToString()) : null;
            loginState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
        }

        //关闭窗口
        private void Close()
        {
            _closeMethod.Invoke();
        }

        //读取保存的密码
        private void LoadConfig()
        {
            SavePass = Comm.CFG.IsSavePass;
            UserName = Comm.CFG.IsSavePass ? Comm.CFG.SavedUser : "";
            LogingIn = false;
            ConnectToServer();
        }

        //打开设置窗口
        private void OpenSet()
        {
            ConnState = "正在设置服务器地址";
            _connCount = 0;
            Views.ServerSetView w = new Views.ServerSetView();
            w.Owner = Win;
            w.ShowDialog();
            ConnectToServer();
        }

        #endregion 方法
    }
}